package com.lzs.bootsafety.common.config.shiro.session;

import com.lzs.bootsafety.business.moni.entity.SysOnlineUser;
import com.lzs.bootsafety.business.moni.service.SysOnlineUserService;
import com.lzs.bootsafety.common.config.shiro.ShiroService;
import com.lzs.bootsafety.common.util.SpringContextAware;
import com.lzs.bootsafety.common.util.enums.OnlineStatus;
import com.lzs.bootsafety.common.util.http.LocationByIP;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.Date;

/**
 * @Author LiuZhanShi
 * @Date 2020/7/30 15:11
 * @Version 1.0
 */
public class MySessionDAO  extends EnterpriseCacheSessionDAO {
    @Autowired
    private ShiroService shiroService;

    /**
     * 上次同步数据库的时间戳
     */
    private static final String LAST_SYNC_DB_TIMESTAMP = MySessionDAO.class.getName() + "LAST_SYNC_DB_TIMESTAMP";


    public MySessionDAO() {
        super();
    }

    public MySessionDAO(long expireTime) {
        super();
    }
    @Override
    protected Session doReadSession(Serializable sessionId) {
        return shiroService.getSession(sessionId);
    }
    @Override
    public void update(Session session) throws UnknownSessionException {
        super.update(session);
    }
    @Override
    protected void doDelete(Session session) {
        OnlineSession onlineSession = (OnlineSession) session;
        if (null == onlineSession){
            return;
        }
        onlineSession.setStatus(OnlineStatus.off_line);
        shiroService.deleteSession(onlineSession);
    }


    /**
     * 更新会话；如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用
     */
    public void syncToDb(OnlineSession onlineSession) {
        Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP);
        if (lastSyncTimestamp != null) {
            boolean needSync = true;
            long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime();
            if (deltaTime < 1 * 60 * 1000) {
                // 时间差不足 无需同步
                needSync = false;
            }
            // isGuest = true 访客
            boolean isGuest = onlineSession.getUserId() == null || onlineSession.getUserId() == 0L;

            // session 数据变更了 同步
            if (!isGuest == false && onlineSession.isAttributeChanged()) {
                needSync = true;
            }

            if (!needSync) {
                return;
            }
        }
        // 更新上次同步数据库时间
        onlineSession.setAttribute(LAST_SYNC_DB_TIMESTAMP, onlineSession.getLastAccessTime());
        // 更新完后 重置标识
        if (onlineSession.isAttributeChanged()) {
            onlineSession.resetAttributeChanged();
        }
        syncSessionToDb(onlineSession);
    }
    public void syncSessionToDb(OnlineSession session){
        SysOnlineUser online = new SysOnlineUser();
        online.setSessionId(String.valueOf(session.getId()));
        online.setDeptName(session.getDeptName());
        online.setLoginName(session.getLoginName());
        online.setStartTimestamp(session.getStartTimestamp());
        online.setLastAccessTime(session.getLastAccessTime());
        online.setExpireTime(session.getTimeout());
        online.setIpaddr(session.getHost());
        online.setLoginLocation( LocationByIP.request(session.getHost()));
        online.setBrowser(session.getBrowser());
        online.setOs(session.getOs());
        online.setStatus(session.getStatus());
        SpringContextAware.getBeans(SysOnlineUserService.class).saveOnline(online);
    }

}
